package qiniu.voidcepc.voicepc.demos.web.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.NoHandlerFoundException;
import qiniu.voidcepc.voicepc.demos.web.vo.ApiResponse;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 全局异常处理器
 * 统一处理Controller层抛出的各类异常，返回标准化的ApiResponse响应
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = Logger.getLogger(GlobalExceptionHandler.class.getName());

    /**
     * 处理通用业务异常
     * @param e 业务异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ApiResponse<?>> handleBusinessException(BusinessException e, HttpServletRequest request) {
        logger.log(Level.WARNING, "业务异常: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.OK).body(
                ApiResponse.error(e.getErrorCode(), e.getMessage())
        );
    }

    /**
     * 处理文件上传异常
     * @param e 文件上传异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(MultipartException.class)
    public ResponseEntity<ApiResponse<?>> handleMultipartException(MultipartException e, HttpServletRequest request) {
        logger.log(Level.SEVERE, "文件上传异常: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
                ApiResponse.error("400", "文件上传失败，请检查文件格式和大小")
        );
    }

    /**
     * 处理IO异常
     * @param e IO异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(IOException.class)
    public ResponseEntity<ApiResponse<?>> handleIOException(IOException e, HttpServletRequest request) {
        logger.log(Level.SEVERE, "IO异常: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
                ApiResponse.error("500", "服务器IO处理失败")
        );
    }

    /**
     * 处理空指针异常
     * @param e 空指针异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(NullPointerException.class)
    public ResponseEntity<ApiResponse<?>> handleNullPointerException(NullPointerException e, HttpServletRequest request) {
        logger.log(Level.SEVERE, "空指针异常: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
                ApiResponse.error("500", "服务器处理错误")
        );
    }

    /**
     * 处理非法参数异常
     * @param e 非法参数异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ApiResponse<?>> handleIllegalArgumentException(IllegalArgumentException e, HttpServletRequest request) {
        logger.log(Level.WARNING, "非法参数异常: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
                ApiResponse.error("400", "参数错误: " + e.getMessage())
        );
    }

    /**
     * 处理未声明的异常（通常是被包装的运行时异常）
     * @param e 未声明的异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(UndeclaredThrowableException.class)
    public ResponseEntity<ApiResponse<?>> handleUndeclaredThrowableException(UndeclaredThrowableException e, HttpServletRequest request) {
        Throwable cause = e.getUndeclaredThrowable();
        logger.log(Level.SEVERE, "未声明的异常: {0}, 请求路径: {1}", new Object[]{cause != null ? cause.getMessage() : e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
                ApiResponse.error("500", "服务器处理错误")
        );
    }

    /**
     * 处理资源未找到异常
     * @param e 资源未找到异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<ApiResponse<?>> handleNoHandlerFoundException(NoHandlerFoundException e, HttpServletRequest request) {
        logger.log(Level.WARNING, "资源未找到: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(
                ApiResponse.error("404", "请求的资源不存在")
        );
    }

    /**
     * 处理所有其他未明确捕获的异常
     * @param e 异常对象
     * @param request HTTP请求对象
     * @return 标准API响应
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<?>> handleGenericException(Exception e, HttpServletRequest request) {
        logger.log(Level.SEVERE, "未处理的异常: {0}, 请求路径: {1}", new Object[]{e.getMessage(), request.getRequestURI()});
        e.printStackTrace(); // 在生产环境中，可以改为记录到日志系统
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
                ApiResponse.error("500", "服务器内部错误")
        );
    }
}